package com.yunji.cabinet.dao.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.google.common.base.Optional;
import com.yunji.base.bo.ChangeBindBO;
import com.yunji.cabinet.bo.*;
import com.yunji.cabinet.dao.ICabinetDao;
import com.yunji.cabinet.domain.ContainerDO;
import com.yunji.cabinet.mapper.CabinetMapper;
import com.yunji.cabinet.params.SpecificUpgradeCabinetParam;
import com.yunji.common.base.BaseDaoImpl;
import com.yunji.common.utils.bean.BeanUtils;
import com.yunji.storage.dto.StorageFiledDTO;
import org.springframework.stereotype.Repository;

import javax.annotation.Resource;
import java.util.List;

/**
 * @Project: yunji-coffee
 * @Package: com.yunji.cabinet.dao.impl
 * @Title: CabinetDaoImpl
 * <p>
 * History:
 * Date                     Version     Author          Summary
 * ============================================================
 * 2024-10-24 13:59:09      V1.0        HuaAo       新建类
 */
@Repository
public class CabinetDaoImpl extends BaseDaoImpl<CabinetMapper, ContainerDO> implements ICabinetDao {

    @Resource
    CabinetMapper cabinetMapper;

//    @Override
//    public List<Map<String, Object>> countCabinet(String filed) {
//        QueryWrapper<Cabinet> wrapper = new QueryWrapper<>();
//        wrapper.select(filed + ", count(*) AS containerNums").groupBy(filed);
//        wrapper.lambda().eq(Cabinet::getDelFlag, LogicCode.NO);
//        return cabinetMapper.selectMaps(wrapper);
//    }

    @Override
    public Long getBelongIdByContainerId(Long containerId) {
        LambdaQueryWrapper<ContainerDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(ContainerDO::getBelongId).eq(ContainerDO::getContainerId, containerId);
        return getOne(wrapper).getBelongId();
    }

    @Override
    public List<ContainerDO> search(CabinetListQueryBO bo) {
        return list(new LambdaQueryWrapper<ContainerDO>()
                .eq(BeanUtils.isNotNull(bo.getAgentId()), ContainerDO::getAgentId, bo.getAgentId())
                .eq(BeanUtils.isNotNull(bo.getSiteId()), ContainerDO::getSiteId, bo.getSiteId())
                .isNull(!bo.isWhetherBind(), ContainerDO::getBelongId)
                .isNotNull(bo.isWhetherBind(), ContainerDO::getBelongId)
                .like(BeanUtils.isNotNull(bo.getVersion()), ContainerDO::getVersion, bo.getVersion())
                .like(BeanUtils.isNotNull(bo.getContainerName()), ContainerDO::getContainerName, bo.getContainerName())
                .in(BeanUtils.isNotNull(bo.getTypeIds()), ContainerDO::getTypeCode, bo.getTypeIds())
                .in(BeanUtils.isNotNull(bo.getOnlineStatusList()), ContainerDO::getOnlineStatus, bo.getOnlineStatusList())
                .in(BeanUtils.isNotNull(bo.getAgentIds()), ContainerDO::getAgentId, bo.getAgentIds())
                .in(BeanUtils.isNotNull(bo.getSiteIds()), ContainerDO::getSiteId, bo.getSiteIds())
                .in(BeanUtils.isNotNull(bo.getVersionList()), ContainerDO::getVersion, bo.getVersionList()));
        //.in(BeanUtils.isNotNull(bo.getChipTypeList()), CabinetDO::getChipType, bo.getChipTypeList()));
    }

    @Override
    public ContainerDO select(CabinetSelectQueryBo bo) {
        return getOne(queryBoBuild(bo));
    }

    @Override
    public boolean changeAgent(ChangeBindBO bo) {
        return update(new LambdaUpdateWrapper<ContainerDO>()
                .set(ContainerDO::getBelongId, bo.getBelongId())
                .set(ContainerDO::getAgentId, bo.getAgentId())
                .eq(ContainerDO::getSiteId, bo.getSiteId()));
    }

    @Override
    public boolean existsCabinet(CabinetCheckBO bo) {
        return lambdaQuery().eq(BeanUtils.isNotNull(bo.getContainerId()), ContainerDO::getContainerId, bo.getContainerId())
                .eq(BeanUtils.isNotNull(bo.getChipImei()), ContainerDO::getChipImei, bo.getChipImei())
                .eq(BeanUtils.isNotNull(bo.getTypeId()), ContainerDO::getTypeCode, bo.getTypeId()).exists();
    }

    @Override
    public boolean resetCabinetQrcode(Long cabinetId) {
        return baseMapper.resetCabinetQrcode(cabinetId) > 0;
    }

    @Override
    public int countCabinet(CabinetCountBO bo) {
        Long count = lambdaQuery().eq(BeanUtils.isNotNull(bo.getAgentId()), ContainerDO::getAgentId, bo.getAgentId()).count();
        return Optional.fromNullable(count).or(0L).intValue();
    }

    @Override
    public List<String> searchTableField(StorageFiledDTO param) {
        return baseMapper.searchTableField(param);
    }

    @Override
    public List<Long> searchContainerIdsBySiteId(Long siteId) {
        return listObjs(new LambdaQueryWrapper<ContainerDO>()
                .select(ContainerDO::getContainerId)
                .eq(ContainerDO::getSiteId, siteId));
    }

    @Override
    public ContainerDO getByQrcode(String qrCode) {
        return lambdaQuery().eq(ContainerDO::getQrcode, qrCode).one();
    }

    @Override
    public List<ContainerDO> specificUpgradeCabinetList(SpecificUpgradeCabinetBO bo) {
        return list(new LambdaQueryWrapper<ContainerDO>()
                .isNull(!bo.isWhetherBind(), ContainerDO::getBelongId)
                .isNotNull(bo.isWhetherBind(), ContainerDO::getBelongId)
                .like(BeanUtils.isNotNull(bo.getContainerName()), ContainerDO::getContainerName, bo.getContainerName())
                .in(BeanUtils.isNotNull(bo.getTypeIds()), ContainerDO::getTypeCode, bo.getTypeIds())
                .in(BeanUtils.isNotNull(bo.getOnlineStatusList()), ContainerDO::getOnlineStatus, bo.getOnlineStatusList())
                .in(BeanUtils.isNotNull(bo.getAgentIds()), ContainerDO::getAgentId, bo.getAgentIds())
                .in(BeanUtils.isNotNull(bo.getSiteIds()), ContainerDO::getSiteId, bo.getSiteIds())
                .in(BeanUtils.isNotNull(bo.getVersionList()), ContainerDO::getVersion, bo.getVersionList())
                //.in(BeanUtils.isNotNull(bo.getChipTypeList()), CabinetDO::getChipType, bo.getChipTypeList())
                .in(BeanUtils.isNotNull(bo.getExistContainerIds()), ContainerDO::getContainerId, bo.getExistContainerIds())
                .notIn(BeanUtils.isNotNull(bo.getIgnoreContainerIds()), ContainerDO::getContainerId, bo.getIgnoreContainerIds())
                .and(BeanUtils.isNotNull(bo.getChipTypeList()),w ->
                        bo.getChipTypeList().forEach(a-> w.like(ContainerDO::getVersion,'-'+a+'-').or())
                )
                .orderByDesc(ContainerDO::getCreateTime));
    }

    @Override
    public List<ContainerDO> specificUpgradeCabinetVOList(SpecificUpgradeCabinetParam bo) {
        return pageList(bo, new LambdaQueryWrapper<ContainerDO>()
                .isNull(!bo.isWhetherBind(), ContainerDO::getBelongId)
                .isNotNull(bo.isWhetherBind(), ContainerDO::getBelongId)
                .like(BeanUtils.isNotNull(bo.getContainerName()), ContainerDO::getContainerName, bo.getContainerName())
                .in(BeanUtils.isNotNull(bo.getTypeIds()), ContainerDO::getTypeCode, bo.getTypeIds())
                .in(BeanUtils.isNotNull(bo.getOnlineStatusList()), ContainerDO::getOnlineStatus, bo.getOnlineStatusList())
                .in(BeanUtils.isNotNull(bo.getAgentIds()), ContainerDO::getAgentId, bo.getAgentIds())
                .in(BeanUtils.isNotNull(bo.getSiteIds()), ContainerDO::getSiteId, bo.getSiteIds())
                .in(BeanUtils.isNotNull(bo.getVersionList()), ContainerDO::getVersion, bo.getVersionList())
//                .in(BeanUtils.isNotNull(bo.getChipTypeList()), CabinetDO::getChipType, bo.getChipTypeList())
                .and(BeanUtils.isNotNull(bo.getChipTypeList()),w ->
                        bo.getChipTypeList().forEach(a-> w.like(ContainerDO::getVersion,'-'+a+'-').or())
                )
                .orderByDesc(ContainerDO::getCreateTime));
    }

    @Override
    public boolean containerExistsSiteLocation(List<Long> locationIds) {
        return lambdaQuery().in(ContainerDO::getLocationId, locationIds).exists();
    }

    @Override
    public boolean existsCabinet(CabinetSelectQueryBo bo) {
        return exists(new LambdaQueryWrapper<ContainerDO>()
                .eq(BeanUtils.isNotNull(bo.getChipImei()), ContainerDO::getChipImei, bo.getChipImei())
                .or().eq(BeanUtils.isNotNull(bo.getQrcode()), ContainerDO::getQrcode, bo.getQrcode()));
    }

    @Override
    public ContainerDO getByImei(String imei) {
        return lambdaQuery().eq(ContainerDO::getChipImei, imei).one();
    }

    @Override
    public String getImeiByQrcode(String qrcode) {
        return Optional.fromNullable(lambdaQuery().select(ContainerDO::getChipImei).eq(ContainerDO::getQrcode, qrcode).one())
                .transform(ContainerDO::getChipImei).orNull();
    }

    @Override
    public String getImeiById(Long id) {
        return Optional.fromNullable(getById(id))
                .transform(ContainerDO::getChipImei).orNull();
    }

    private static LambdaQueryWrapper<ContainerDO> queryBoBuild(CabinetSelectQueryBo bo) {
        return new LambdaQueryWrapper<ContainerDO>()
                .eq(BeanUtils.isNotNull(bo.getChipSn()), ContainerDO::getChipSn, bo.getChipSn())
                .eq(BeanUtils.isNotNull(bo.getChipImei()), ContainerDO::getChipImei, bo.getChipImei())
                .and(BeanUtils.isNotNull(bo.getQrcode()), w -> {
                    w.eq(ContainerDO::getQrcode, bo.getQrcode()).or().eq(ContainerDO::getChipImei, bo.getQrcode());
                });
    }

}